//
//  JYTNFCApi.m
//  CQCKJYTMacros
//
//  Created by 九爷 on 2023/9/12.
//

#import "JYTNFCApi.h"

#import "JYTNFCCoreTool.h"

#import <JYTMacros.h>
#import <LYExtension/LYExtension.h>
#import <LYNetworkService/LYNetworkService.h>

static NSString const* tenantCode = @"004000";
static NSString *const readPath = @"ReadCard";
static NSString *const writePath = @"Credit";
static NSString *const exceptRevertPath = @"ExceptRevert";
static NSString *const nfc_time_key = @"nfc_time";
static NSString *const nfc_token_key = @"nfc_token";

@interface JYTNFCApi ()

@property (nonatomic, copy, readonly) NSString *accessToken;
@property (nonatomic, strong) LYHttp *http;

@end

@implementation JYTNFCApi

- (void)login:(void (^)(BOOL, NSString *))complation {
    if (![NSString lyIsEmptyStr:self.accessToken]) {
        NSLog(@"不用登录");
        !complation ?: complation(YES, @"");
        return;
    }
    
    [self.http requestWithType:LYHttpRequestTypeNormal responseType:LYHttpResponseTypeJson methodType:LYHttpMethodTypePost headers:^NSDictionary *{
        return @{@"Authorization":@"Basic Y2hlemFpamk6Y2hlemFpamlfc2VjcmV0"};
    } url:[NSString stringWithFormat:@"%@/emptech-auth/token", [self _getHost]] parameters:@{@"account":@"nfc", @"password":@"123456", @"tenantCode":tenantCode} complation:^(BOOL success, id respObj, NSInteger errorCode, NSTimeInterval timestamp, NSDictionary *header) {
        if (success) {
            if ([respObj[@"code"] integerValue] == 200) {
                [NSObject saveKeychainWithObject:respObj[@"data"][@"accessToken"] service:kBundleIdentifier key:nfc_token_key];
                [NSObject saveKeychainWithObject:[@(timestamp) stringValue] service:kBundleIdentifier key:nfc_time_key];
//                self->_accessToken = respObj[@"data"][@"accessToken"];
                !complation ?: complation(YES, @"");
            } else {
                !complation ?: complation(NO, @"业务错误，请稍后重试");
            }
        } else {
            !complation ?: complation(NO, [self _networkErrorStrWithCode:errorCode]);
        }
    }];
}

- (void)requestCardApdusWithCardTypePath:(NSString *)cardTypePath apdusResult:(NSDictionary *)adpusResult optType:(JYTNFCOptType)optType transData:(NSDictionary *)transData requestType:(NSString *)requestType ats:(NSString *)ats uid:(NSString *)uid seqNo:(NSString *)seqNo chargeFee:(NSString *)chargeFee orderNo:(NSString *)orderNo cardNo:(NSString *)cardNo checkGreyStatus:(BOOL)checkGreyStatus result:(NSDictionary *)result complation:(void (^)(BOOL, BOOL, NSString *, NSArray *, NSDictionary *, NSString *, NSString *, NSString *, NSString *, NSString *, BOOL, NSString *, BOOL, NSString *, BOOL))complation {
    NSMutableDictionary *param = NSMutableDictionary.new;
    [param setObject:@"2.0" forKey:@"version"];
    [param setObject:@"md5" forKey:@"sign_type"];
    [param setObject:tenantCode forKey:@"tenantCode"];
    [param setObject:@"999999999999" forKey:@"terminal_no"];
    [param setObject:[NSDate lyCurrentTimeWithFormat:@"yyyyMMddHHmmss"] forKey:@"timestamp"];
    [param setObject:requestType forKey:@"process"];
    [param setObject:@"chongqingcity" forKey:@"customer_code"];
    [param setObject:@"00" forKey:@"dataType"];
    [param setObject:@"nfc" forKey:@"operator_no"];
    [param setObject:ats forKey:@"ats"];
    [param setObject:seqNo forKey:@"seq_no"];
    [param setObject:@"" forKey:@"result_code"];
    [param setObject:@"" forKey:@"result_msg"];
    [param setObject:adpusResult forKey:@"apdusResult"];
    [param setObject:transData forKey:@"trans_data"];
    [param setObject:result forKey:@"result"];
    [param setObject:uid forKey:@"uid"];
    
    //特殊参数 路径获取
    NSString *path = @"";
    NSDictionary *paramsDict = @{};
    switch (optType) {
        case JYTNFCOptTypeWrite:
            path = writePath;
            paramsDict = @{@"rechargeFee":chargeFee, @"tradeSmallType":@"10", @"tradeType":@"12", @"orderNo":orderNo, @"cardNo":cardNo};
            break;
        case JYTNFCOptTypeRead:
            path = readPath;
            paramsDict = @{@"isCheckBLK":@"00"};
            break;
        case JYTNFCOptTypeExceptRevert:
            path = exceptRevertPath;
            break;
        default:
            break;
    }
    [param setObject:paramsDict forKey:@"params"];
    
    NSString *sign = [JYTNFCCoreTool signStr:[param copy]];
    [param setObject:[sign uppercaseString] forKey:@"sign"];
    
    NSLog(@"请求参数:\n%@", adpusResult);
    NSString *url = [NSString stringWithFormat:@"%@/emptech-ykt-cardbusiness/CQCITY/%@/%@", [self _getHost], cardTypePath, path];
    NSLog(@"请求地址:%@", url);
    
    [self.http requestWithType:LYHttpRequestTypeJson responseType:LYHttpResponseTypeJson methodType:LYHttpMethodTypePost headers:^NSDictionary *{
        return @{@"blade-auth": [NSString stringWithFormat:@"Bearer %@", self.accessToken]};
    } url:url parameters:[param copy] complation:^(BOOL success, id respObj, NSInteger errorCode, NSTimeInterval timestamp, NSDictionary *header) {
        NSLog(@"%@", respObj);
        if ([respObj[@"code"] integerValue] == 200) {
            //成功
            NSDictionary *data = respObj[@"data"];
            NSString *processType = data[@"process"];
            BOOL isFinish = ([requestType isEqualToString:@"end"] && [processType isEqualToString:@"end"]);
            NSMutableArray *adpus = [NSMutableArray arrayWithArray:[data[@"apdus"] jsonStrToObject]];
            NSMutableDictionary *transData = [NSMutableDictionary dictionaryWithDictionary:data[@"trans_data"]];
            NSString *seqNo = [NSString lyFormatStr:data[@"seq_no"]];
            
            //特殊处理返回的信息
            if ([data[@"result_code"] isEqualToString:@"SUCCESS"]) {
                BOOL isGray = NO;
                NSString *chargeFee = @"0";
                if (optType == JYTNFCOptTypeWrite) {
                    if (checkGreyStatus) {
                        isGray = [data[@"result"][@"isGrey"] isEqualToString:@"1"];
                    } else {
                        isGray = NO;
                    }
                    chargeFee = data[@"result"][@"rechargeFee"];
                }
                
                //
                isGray = NO;
                
                if (isGray) {
                    //灰交易 应该结束后面的请求
                    !complation ?: complation(NO, NO, nil, adpus, transData, processType, seqNo, cardNo, @"", @"", YES, @"", isGray, chargeFee, NO);
                } else {
                    if (isFinish) {
                        NSString *cardNo = data[@"result"][@"cardNo"];
                        NSString *cardBalace = @"0";
                        if (optType == JYTNFCOptTypeRead) {
                            cardBalace = data[@"result"][@"cardRealBalance"];
                        } else {
                            unsigned long long result = 0;
                            NSScanner *scanner = [NSScanner scannerWithString:data[@"apdusResult"][@"aftBalance"]];
                            [scanner scanHexLongLong:&result];
                            NSLog(@"result = %llu",result);
                            cardBalace = [@(result) stringValue];
                        }
                        NSString *cityCode = (optType == JYTNFCOptTypeRead) ? data[@"result"][@"cityCode"] : @"";
                        NSString *cardStatusStr = (optType == JYTNFCOptTypeRead) ? data[@"result"][@"cardStatusDes"] : @"";
                        
                        BOOL isNormalCard = YES;
                        
                        if ([NSString lyIsEmptyStr:data[@"result"][@"cardType"]]) {
                            isNormalCard = NO;
                            cardStatusStr = @"未知无效卡";
                        } else {
                            isNormalCard = (optType == JYTNFCOptTypeRead) ? [data[@"result"][@"cardStatus"] isEqualToString:@"00"] : YES;
                        }
                        !complation ?: complation(YES, isFinish, nil, adpus, transData, processType, seqNo, cardNo, cardBalace, cityCode, isNormalCard, cardStatusStr, isGray, chargeFee, NO);
                    } else {
                        !complation ?: complation(YES, isFinish, nil, adpus, transData, processType, seqNo, cardNo, @"", @"", YES, @"", NO, @"", NO);
                    }
                }
            } else {
                if ([data[@"result_msg"] isEqualToString:@"交易已调整，前次交易失败"] || [data[@"result_msg"] isEqualToString:@"交易已调整，前次交易成功"]) {
                    !complation ?: complation(YES, YES, @"", nil, nil, @"", @"", @"", @"", @"", NO, @"", NO, @"", NO);
                } else {
                    !complation ?: complation(NO, NO, [NSString lyIsEmptyStr:data[@"result_msg"]] ? @"读卡错误，请稍后重试" : data[@"result_msg"], nil, nil, @"", @"", @"", @"", @"", NO, @"", NO, @"", NO);
                }
            }
        } else {
            //失败
            !complation ?: complation(NO, NO, [self _networkErrorStrWithCode:errorCode], nil, nil, @"", @"", @"", @"", @"", NO, @"", NO, @"", NO);
        }
    }];
}

- (NSString *)_getHost {
    if ([JYTNFCCoreTool instance].isDebugEnv) {
        return @"http://192.168.1.4:10067";
    }
    return @"http://st.cqckss.com:8496";
}

- (NSString *)_networkErrorStrWithCode:(NSInteger)code {
    NSString *errorStr = @"系统错误，请重试";
    switch (code) {
        case NSURLErrorNotConnectedToInternet:
        case NSURLErrorCannotConnectToHost:
        case NSURLErrorNetworkConnectionLost:
            errorStr = @"网络异常，请重试";
            break;
        case NSURLErrorTimedOut:
            errorStr = @"网络不给力，请重试";
            break;
        default:
            break;
    }
    return errorStr;
}

- (LYHttp *)http {
    if (!_http) {
        _http = [[LYHttp alloc] init];
        [_http setRequestTimeout:10.0];
    }
    return _http;
}

- (NSString *)accessToken {
    NSString *token = [NSObject getKeychainObjectWithService:kBundleIdentifier key:nfc_token_key];
    NSString *time = [NSObject getKeychainObjectWithService:kBundleIdentifier key:nfc_time_key];
    NSString *tokenTime = [NSDate lyConvertToTimeWithTimestamp:time timeFormat:@"yyyy-MM-dd" timestampType:LYTimestampTypeSecond];
    NSString *nowTime = [NSDate lyConvertToTimeWithTimestamp:[NSDate lyCurrentTimestampWithType:LYTimestampTypeSecond] timeFormat:@"yyyy-MM-dd" timestampType:LYTimestampTypeSecond];
//    NSInteger result = [NSDate lyCompareDayWithCheckDay:[NSDate lyDateByTimeStr:nowTime timeFormat:@"yyyy-MM-dd"] compareDay:[NSDate lyDateByTimeStr:tokenTime timeFormat:@"yyyy-MM-dd"] withFormat:@"yyyy-MM-dd"];
    NSInteger result = [NSDate lyCompareDayWithCheckDay:[NSDate lyDateByTimeStr:tokenTime timeFormat:@"yyyy-MM-dd"] compareDay:[NSDate lyDateByTimeStr:nowTime timeFormat:@"yyyy-MM-dd"] withFormat:@"yyyy-MM-dd"];
    if (result == -1) {
        [NSObject removeKeychainObjectWithService:kBundleIdentifier key:nfc_token_key error:nil];
        [NSObject removeKeychainObjectWithService:kBundleIdentifier key:nfc_time_key error:nil];
        return nil;
    }
    return token;
}

@end
